package com.example.spring.redis.common.config;

import com.example.spring.redis.common.constants.CommonConstants;
import com.google.common.collect.Sets;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

import javax.validation.Valid;
import java.time.Duration;
import java.util.Objects;

import static com.example.spring.redis.common.constants.CommonConstants.GLOBAL_CACHE_HOLDER;

/**
 * <p>
 *
 * </p>
 *
 * @author Ashe
 * @version V1.0.0
 * @date 2019/12/27 0027$ 11:00$
 * @modificationHistory=========================逻辑或功能性重大变更记录
 * @modify By: {修改人} 2019/12/27 0027$
 * @modify reason: {方法名}:{原因}
 * ...
 * @since V1.0.0
 */
@Configuration
public class CacheManagerConfiguration {

    @Value("${spring.redis.port:0}")
    private Integer redisPort;


    @Bean
    @ConditionalOnMissingBean(value = RedisCacheManager.class)
    public SimpleCacheManager simpleCacheManager() {
        SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
        ConcurrentMapCacheFactoryBean concurrentMapCacheFactoryBean = new ConcurrentMapCacheFactoryBean();
        concurrentMapCacheFactoryBean.setName(GLOBAL_CACHE_HOLDER);
        concurrentMapCacheFactoryBean.setStore(CommonConstants.GLOBAL_CACHE_MAP);
        concurrentMapCacheFactoryBean.afterPropertiesSet();
        simpleCacheManager.setCaches(Sets.newHashSet(concurrentMapCacheFactoryBean.getObject()));
        return simpleCacheManager;
    }

    /**
     * 单点连接配置
     *
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
        if (redisPort != 0) {
            RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                    .entryTtl(Duration.ofHours(1)); // 设置缓存有效期一小时
            return RedisCacheManager
                    .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
                    .cacheDefaults(redisCacheConfiguration).build();
        }
        /**
         * 集群连接配置
         * https://blog.csdn.net/qq_32090861/article/details/84833942
         */
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofHours(1)); // 设置缓存有效期一小时
        return RedisCacheManager
                .RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory)
                .cacheDefaults(redisCacheConfiguration).build();
    }

}

